#pragma once

#include <map>
#include <string>
#include <vector>
#include <list>

//For Gzip decode
#define ZLIB_WINAPI
#include <zlib.h>
#pragma comment(lib, "zlibwapi.lib")

//For regex Searching
#include <atlrx.h>
#include <xmllite.h>
#pragma comment(lib, "xmllite.lib")

using std::map;
using std::string;
using std::wstring;
using std::vector;
using std::list;

//Define the buffersize of Web Content
#define BUFFER_GZ_HTTP_STREAM		2*1024*1024		// 2M
#define BUFFER_DEC_HTTP_STREAM		2*1024*1024		// 2M
#define BUFFER_PLAIN_HTTP_STREAM	4*1024*1024		// 4M

#define BUFFER_GZ_HTTP_STREAM_S		1*1024*1024		// 1M
#define BUFFER_DEC_HTTP_STREAM_S	2*1024*1024		// 2M
#define BUFFER_PLAIN_HTTP_STREAM_S	2*1024*1024		// 2M

class CHttpStreamHandler
{
//Type define
public:

	enum {
		ACCEPTENCODING = 0,
		CONNECTION,
		COOKIE,
		HOST,
		PRAGMA,
		REFERER,
		USERAGENT,

		//Resp Header
		CONTENTENCODING,
		CONTENTLENGTH,
		CONTENTDISPOSITION,
		CONTENTMD5,
		CONTENTTYPE,
		ETAG,
		LASTMODIFIED,
		LOCATION,
		RETRYAFTER,
		SETCOOKIE,
		TRANSFERENCODING,
		CONTENTRANGE,

		//FTP Resp
		FILESTATUS,
		ERRORLOGIN,
		FILENOEXIST,
		MOREINFO,
		READYTRANSFER
	};

	static map<short, string> REQ_HEADER;
	static map<short, string> RESP_HEADER;

public:
	//JShare Data
	typedef struct _JSIterm
	{
		enum {
			JSITEMID = 0,
			JSFILEKB,
			JSFILENAME
		};

		wstring wstrID;
		size_t uiFileSizeKB;
		wstring wstrFileName;

		_JSIterm() : wstrID(L""), uiFileSizeKB(0), wstrFileName(L"") {}
		_JSIterm(WCHAR* wcID, size_t uiFileSizeKB, WCHAR* wcFileName) : wstrID(wcID), uiFileSizeKB(uiFileSizeKB), wstrFileName(wcFileName) {}
	} JSItem;

public:
	static UINT GetHeaderContentLength(vector<string>* pvecstrHeaders);
	static bool IsGzipContent(vector<string>* pvecstrHeaders);
	static bool IsChunkedTransfer(vector<string>* pvecstrHeaders);
	static bool IsCaptchaNeeded(LPWSTR lpwstrContent);
	static bool GetCaptchaLink(LPWSTR lpwstrContent, string& strCaptchaLink);
	static HANDLE CreateTempFileWithExtA(LPSTR lpstrExt, string& strTempFileName);
	static bool GetDownLoadLinkFromJSPage(LPWSTR lpwstrContent, string& strFileLink, string& strDownLoadLink);

	static void RemoveLineBreak(LPWSTR lpwstrContent);
	static void RemoveLineBreakA(LPSTR lpcstrContent);
	static LRESULT DecodeGzipStream(CHAR* pcInStream, UINT uiCompSize, CHAR* pcOutStream, bool isBigBuffer = true);
	static int JSTwoLayerSearch(vector<JSItem>& vecJSItems, WCHAR* UContentBuffer, const WCHAR* pwcOuterRegx, const WCHAR* pwcBlockRegx);
	static int JSGetSecIP(string& strURL, map<string, string>& mapSecIp, WCHAR* UContentBuffer, const WCHAR* pwcSecIpRegx);
};




